<?php
namespace Controllers;

class Controller 
{
    protected $container;
    protected $key = '5c515817ba22e68f1930957c851c91bc';
    // 用户表
    protected $userTable = 'user';
    // 用户角色关系表
    protected $roleUserTable = 'role_user';
    // 节点表
    protected $nodeTable = 'node';
    // 权限表
    protected $accessTable = 'access';
    // 角色表
    protected $roleTable = 'role';
    // 项目表
    protected $projectTable = 'project';
    // 仓库类别表
    protected $typeStoreTable = 'type_store';
    // 仓库物品表
    protected $storeHouseTable = 'storehouse';
    // 申购表的属性
    protected $applyTable = 'apply_table';
    // 项目与申购表的关系表
    protected $roleApplyTable = 'role_apply';
    // 入库记录
    protected $inRecordTable = 'in_record';
    // 出库记录
    protected $outRecordTable = 'out_record';
    // 领用&退库表
    protected $reTable = 're_table';
    // 人员项目关系表
    protected $roleProjectTable = 'role_project';
    // 审核记录表
    protected $checkTable = 'check_table';
    // token's payload
    protected $payload;

    
    public function __construct(\Slim\Container $container)
    {
        $this->container = $container;
        date_default_timezone_set('Asia/Shanghai');
        header("Access-Control-Allow-Origin:http://localhost:8080");
        header("Access-Control-Allow-Credentials:true");
        header("Access-Control-Allow-Methods:PUT, GET, POST, DELETE, OPTIONS");
        header("Access-Control-Allow-Headers:Content-Type");       
        ini_set("session.cookie_httponly", 1);
        @session_start();
        //在访问前先检查token是否合法
        // echo $_SESSION['token'];
        if($_SERVER['REQUEST_METHOD'] != 'OPTIONS')
        {
            if(!isset($_SESSION['token']))
            {
                exit(self::invalidToken());
            }
            else
            {
                $token = $_SESSION['token'];
                $payload = self::decode($token, $this->key);
                if(!$payload)
                {
                    exit(self::invalidToken());
                }
                else
                {
                    $this->payload = $payload;
                }
            }
        }
    }

    //暂时先用着别人撸的token代码，slim有jwt组件, 日后再用
    public static function encode(array $payload, string $key, string $alg = 'SHA256')
    {
        $jwt = self::urlsafeBase64Encode(json_encode(['type' => 'JWT', 'alg' => $alg])).'.'.self::urlsafeBase64Encode(json_encode($payload));
        return $jwt.'.'.self::signature($jwt, $key, $alg);
    }

    public static function decode(string $jwt, string $key)
    {
        $tokens = explode('.', $jwt);

        if(count($tokens) != 3)
        {
            return false;
        }

        list($header64, $payload64, $sign) = $tokens;

        $header = json_decode(self::urlsafeBase64Decode($header64), JSON_OBJECT_AS_ARRAY);

        if(empty($header['alg']))
        {
            return false;
        }

        if (self::signature($header64 . '.' . $payload64, $key, $header['alg']) !== $sign)
        {
            return false;
        }

        $payload = json_decode(self::urlsafeBase64Decode($payload64), JSON_OBJECT_AS_ARRAY);

        $time = $_SERVER['REQUEST_TIME'];
        if (isset($payload['iat']) && $payload['iat'] > $time)
            return false;

        if (isset($payload['exp']) && $payload['exp'] < $time)
            return false;

        return $payload;
    }

    public static function signature(string $input, string $key, string $alg)
    {
        return hash_hmac($alg, $input, $key);
    }

    public static function urlsafeBase64Encode($string) {
        $data = base64_encode($string);
        $data = str_replace(array('+','/','='),array('-','_',''),$data);
        return $data;
    }
    
    public static function urlsafeBase64Decode($string) {
        $data = str_replace(array('-','_'),array('+','/'),$string);
        $mod4 = strlen($data) % 4;
        if ($mod4) {
            $data .= substr('====', $mod4);
        }
        return base64_decode($data);
    }

    public static function jsonSuccess($msg = 'no success message',$data = null)
    {
        //        header('Content-type: text/json');
        $result = array(
            "status" => "success",
            "message" => $msg
        );
        if($data)
            $result["data"] = $data;

        return json_encode($result);
    }

    public static function jsonFail($msg = 'no failed message')
    {
        //        header('Content-types: text/json');
        return json_encode(array(
            "status" => "fail",
            "message" => $msg
        ));
    }

    public static function invalidToken()
    {
        return json_encode(array(
            'status' => 'invalid Token',
            'message' => 'invalid Token'
        ));
    }
    public function getUserId()
    {
        return $this->payload['id'];
    }

    public function getUserUid()
    {
        return $this->payload['uid'];
    }
    
    public function getUserPhone()
    {
        return $this->payload['phone'];
    }

    public function getUsername()
    {
        return $this->payload['username'];
    }
    //PHP stdClass Object转array  
    public static function object_array($array) 
    {  
        if(is_object($array)) 
        {  
            $array = (array)$array;  
        } 
        if(is_array($array)) 
        {  
            foreach($array as $key=>$value) 
            {  
                $array[$key] = self::object_array($value);  
            }  
        }  
        return $array;  
    }

    public function getRoleList($user_id)
    {
        return $this->container['db']->select($this->roleUserTable, 'role_id', [
            'user_id' => $user_id
        ]);
    }

    // 检查权限 $id为user的id roleString为能访问该函数的权限
    public function checkAccess($id, $roleString)
    {
        if($_SERVER['REQUEST_METHOD'] != 'OPTIONS')
        {
            $roles = $this->getRoleList($id);
            // var_dump($roles);
            // var_dump($roleString);
            for($i = 0; $i < strlen($roleString); $i++)
            {
                if(in_array($roleString[$i], $roles)) 
                    return 1;
            }
            exit(self::jsonFail('对不起没有权限'));
        }   
    }
}